package com.hopes.bizz.risk.control.evaluate;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hopes.bizz.risk.common.constant.enums.HidDangerBizEnum;
import com.hopes.bizz.risk.common.constant.HidDicConstant;
import com.hopes.bizz.risk.common.constant.RiskDicConstant;
import com.hopes.bizz.risk.common.constant.enums.RiskHidSourceEnum;
import com.hopes.bizz.risk.control.bo.*;
import com.hopes.bizz.risk.control.entity.RiskMeasureTaskRecordEntity;
import com.hopes.bizz.risk.control.service.RiskMeasureTaskRecordService;
import com.hopes.bizz.risk.hid.entity.RiskHidHiddenDangerEntity;
import com.hopes.bizz.risk.hid.service.RiskHidHiddenDangerService;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;


/**
 * @author lyb
 * @version 1.0
 * @description: 计算双预防评估服务
 * @date 2023/7/7 16:39
 */
@Component
public class RiskCalculateService {

    @Resource
    private List<RiskRejectFactorHandler> riskRejectFactorHandlersList;

    @Resource
    private RiskHidHiddenDangerService hidHiddenDangerService;

    @Resource
    private RiskMeasureTaskRecordService riskMeasureTaskRecordService;


    @PostConstruct
    public void init() {
        for (int i = 0, size = riskRejectFactorHandlersList.size(); i < size; i++) {
            RiskRejectFactorHandler riskRejectFactorHandler = riskRejectFactorHandlersList.get(i);
            if (i == size - 1) {
                riskRejectFactorHandler.setNextHandler(null);
            } else {
                riskRejectFactorHandler.setNextHandler(riskRejectFactorHandlersList.get(i + 1));
            }
        }
    }


    public RiskCheckTaskScore calculateRiskCheckTaskScore(RiskEvaluateBo riskEvaluateBo) {
        Date startTime = riskEvaluateBo.getStartTime();
        Date endTime = riskEvaluateBo.getEndTime();
        RiskEffectEvaluationScore riskEffectEvaluationScore = riskEvaluateBo.getRiskEffectEvaluationScore();
        // 查询该时间段的生成的任务
        LambdaQueryWrapper<RiskMeasureTaskRecordEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(RiskMeasureTaskRecordEntity::getTaskDeadlineTime, startTime);
        wrapper.le(RiskMeasureTaskRecordEntity::getTaskDeadlineTime, endTime);
        List<RiskMeasureTaskRecordEntity> riskMeasureTaskRecords = riskMeasureTaskRecordService.list(wrapper);
        // 计划完成的任务数量
        int total = riskMeasureTaskRecords.size();
        // 完成的任务数量
        int finishTotal = 0;
        // 各个任务类型统计
        Map<Integer, Integer> workTypeMap = new HashMap<>();
        // 各个已完成任务类型统计
        Map<Integer, Integer> workTypeFinishMap = new HashMap<>();
        for (RiskMeasureTaskRecordEntity riskMeasureTaskRecord : riskMeasureTaskRecords) {
            Integer workType = riskMeasureTaskRecord.getWorkType();
            Integer taskStatus = riskMeasureTaskRecord.getTaskStatus();
            workTypeMap.compute(workType, (k, v) -> Objects.isNull(v) ? 1 : v + 1);
            if (RiskDicConstant.HIDDEN_CHECK_TASK_STATUS_FINISH.equals(taskStatus)) {
                finishTotal += 1;
                workTypeFinishMap.compute(workType, (k, v) -> Objects.isNull(v) ? 1 : v + 1);
            }
        }
        // 统计扣分项
        Integer deduct = 0;
        Map<Integer, Integer> riskCheckTaskDeductMap = riskEffectEvaluationScore.getRiskCheckTaskDeductMap();
        for (Integer type : riskCheckTaskDeductMap.keySet()) {
            Integer count = workTypeMap.get(type);
            Integer FinishCount = Optional.ofNullable(workTypeFinishMap.get(type)).orElse(0);
            if (Objects.nonNull(count) && count > FinishCount) {
                deduct += riskCheckTaskDeductMap.get(type);
            }
        }
        double res = 0;
        if (finishTotal != 0) {
            res =  NumberUtil.round((double) finishTotal / total, 2).doubleValue() * 50 - deduct;
        }

        RiskCheckTaskScore riskCheckTaskScore = new RiskCheckTaskScore();
        riskCheckTaskScore.setScore(Math.max(res, 0.0));
        riskCheckTaskScore.setRiskTaskFinishCount(finishTotal);
        riskCheckTaskScore.setRiskTaskPlanFinishCount(total);
        riskCheckTaskScore.setRiskTaskResponsibleDeductPoints(deduct);
        return riskCheckTaskScore;
    }


    public HidTaskScore calculateHidTaskScore(RiskEvaluateBo riskEvaluateBo) {
        Date startTime = riskEvaluateBo.getStartTime();
        Date endTime = riskEvaluateBo.getEndTime();
        RiskEffectEvaluationScore riskEffectEvaluationScore = riskEvaluateBo.getRiskEffectEvaluationScore();
        // 非上周截止超期未整改隐患数
        int notRectification;
        // 隐患过少扣分
        double tooLittle;
        RiskHidHiddenDangerEntity hiddenDanger = hidHiddenDangerService.getOneByRiskHid(RiskHidSourceEnum.RISK_CONTROL.getCode());
        if (Objects.isNull(hiddenDanger)) {
            // 没有提交过隐患，减掉所有分数
            tooLittle = riskEffectEvaluationScore.getHidTaskTotalScore();
        } else {
            Date reportDate = hiddenDanger.getReportDate();
            Long betweenDay = DateUtil.between(reportDate, endTime, DateUnit.DAY);
            if (betweenDay < 30) {
                // 30内上传 隐患 不扣分
                tooLittle = 0;
            } else {
                tooLittle = (riskEffectEvaluationScore.getHidNotReport() + (NumberUtil.ceilDiv(betweenDay.intValue() - 30, 7) - 1) * riskEffectEvaluationScore.getHidNotReportLimitWeek());
            }
        }
        LambdaQueryWrapper<RiskHidHiddenDangerEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(RiskHidHiddenDangerEntity::getCorrectiveDeadline, startTime);
        wrapper.le(RiskHidHiddenDangerEntity::getCorrectiveDeadline, endTime);
        wrapper.eq(RiskHidHiddenDangerEntity::getBizCode, HidDangerBizEnum.RISK_POINT_HIDDEN_CHECK.getCode());
        List<RiskHidHiddenDangerEntity> queriedBizCodeAndInDateRangeForList = hidHiddenDangerService.list(wrapper);
        int hidSum = queriedBizCodeAndInDateRangeForList.size();
        long passCount = queriedBizCodeAndInDateRangeForList.stream().filter(item -> HidDicConstant.HID_DANGER_STATUS_PASS.equals(item.getHidStatus())).count();
        // 未整改的数据
        wrapper.eq(RiskHidHiddenDangerEntity::getHidStatus, HidDicConstant.HID_DANGER_WAIT_RECTIFICATION);
        notRectification = hidHiddenDangerService.list(wrapper).size();
        double res;
        if ((hidSum + notRectification) == 0) {
            res = riskEffectEvaluationScore.getHidTaskTotalScore() - tooLittle;
        } else {
            res = NumberUtil.round(((double) passCount / (hidSum + notRectification)), 2).doubleValue() * riskEffectEvaluationScore.getHidTaskTotalScore() - tooLittle;
        }

        HidTaskScore hidTaskScore = new HidTaskScore();
        hidTaskScore.setScore(Math.max(res, 0.0));
        hidTaskScore.setHidTaskFinishCount(Math.toIntExact(passCount));
        hidTaskScore.setHidTaskPlanFinishCount(hidSum + notRectification);
        hidTaskScore.setHidTaskResponsibleDeductPoints(Double.valueOf(tooLittle).intValue());
        return hidTaskScore;
    }

    public NegatedItem calculateRejectScore(RiskEvaluateBo riskEvaluateBo) {
        return riskRejectFactorHandlersList.get(0).calculate(riskEvaluateBo, new NegatedItem());
    }

}
